<!DOCTYPE html>
<html lang="zh">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
	<meta name="keywords" content="dromara.org" />
	<meta name="description" content="dromara.org" />
	<!-- 网页标签标题 -->
	<title>dromara(Open source organization)</title>
	<link rel="shortcut icon" href="/website/img/docsite.ico"/>
	<link rel="stylesheet" href="/website/build/documentation.css" />
</head>
<body>
	<div id="root"><div class="documentation-page" data-reactroot=""><header class="header-container header-container-normal"><div class="header-body"><a href="/website/zh-cn/index.html"><img class="logo" src="/website/img/dromara.png"/></a><div class="search search-normal"><span class="icon-search"></span></div><span class="language-switch language-switch-normal">En</span><div class="header-menu"><img class="header-menu-toggle" src="/website/img/system/menu_gray.png"/><ul><li class="menu-item menu-item-normal"><a href="/website/zh-cn/index.html" target="_self">首页</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal menu-item-normal-active"><a href="#">文档</a><div class="sub-menu"><ul><li><a href="/website/zh-cn/docs/soul/soul.html" target="_self">Soul</a></li><li><a href="/website/zh-cn/docs/hmily/index.html" target="_self">Hmily</a></li></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/blog/index.html" target="_self">博客</a><div class="sub-menu"><ul></ul></div></li><li class="menu-item menu-item-normal"><a href="/website/zh-cn/community/index.html" target="_self">社区</a><div class="sub-menu"><ul></ul></div></li></ul></div></div></header><section class="content-section"><div class="sidemenu" id="menu"><div class="sidemenu-toggle"><img src="https://img.alicdn.com/tfs/TB1E6apXHGYBuNjy0FoXXciBFXa-200-200.png"/></div><ul><li class="menu-item menu-item-level-1"><span>Soul</span><ul><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/soul.html" target="_self">soul介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/team.html" target="_self">团队介绍</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/induction.html" target="_self">soul极简入门</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/db.html" target="_self">数据库设计</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/config.html" target="_self">数据配置流程</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/dataSync.html" target="_self">数据同步原理</a></li><li style="height:36px;overflow:hidden" class="menu-item menu-item-level-2"><a href="/website/zh-cn/docs/soul/metaData.html" target="_self">元数据概念介绍</a></li><li style="height:684px;overflow:hidden" class="menu-item menu-item-level-2"><span>用户使用文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/setup.html" target="_self">搭建soul网关环境</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-http.html" target="_self">http用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dubbo.html" target="_self">dubbo用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-springcloud.html" target="_self">springCloud用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-sofa.html" target="_self">sofa用户</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/selector.html" target="_self">选择器规则详解</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/user-dataSync.html" target="_self">数据同步策略</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-divide.html" target="_self">divide插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-dubbo.html" target="_self">dubbo插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-springcloud.html" target="_self">springcloud插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sofa.html" target="_self">sofa插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rateLimiter.html" target="_self">rateLimiter插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-hystrix.html" target="_self">hystrix插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-monitor.html" target="_self">monitor插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-waf.html" target="_self">waf插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-sign.html" target="_self">sign插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-rewrite.html" target="_self">rewrite插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/plugin-websocket.html" target="_self">websocket支持</a></li></ul></li><li style="height:360px;overflow:hidden" class="menu-item menu-item-level-2"><span>开发者文档<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-filter.html" target="_self">自定义filter</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-plugin.html" target="_self">自定义插件</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-file.html" target="_self">文件上传下载</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-iphost.html" target="_self">自定义解析IP与host</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-result.html" target="_self">自定义返回结果</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-sign.html" target="_self">自定义签名插件算法与验证</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-client.html" target="_self">多语言http客户端接入</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-thread.html" target="_self">线程模型</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/dev-netty.html" target="_self">soul调优</a></li></ul></li><li style="height:144px;overflow:hidden" class="menu-item menu-item-level-2"><span>社区贡献<img style="transform:rotate(0deg)" class="menu-toggle" src="/website/img/system/arrow_down.png"/></span><ul><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/contributor.html" target="_self">贡献者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/committer.html" target="_self">提交者指南</a></li><li class="menu-item menu-item-level-3"><a href="/website/zh-cn/docs/soul/code-conduct.html" target="_self">编码规范</a></li></ul></li></ul></li></ul></div><div class="doc-content markdown-body" id="doc-body"><p>目录：</p>
<ul>
<li><a href="http://www.iocoder.cn/Soul/install/">1. 概述</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">2. 单机部署</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">3. 接入 Dubbo 应用</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">4. 接入 Spring Boot 应用</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">5. 接入 Spring Cloud 应用</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">6. rateLimiter 插件</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">7. hystrix 插件</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/">666. 彩蛋</a></li>
</ul>
<blockquote>
<ul>
<li>作者：<a href="https://github.com/YunaiV">芋道源码</a></li>
<li><a href="http://www.iocoder.cn/Soul/install/?soul">原文地址</a></li>
</ul>
<p>大家好，我是艿艿，一个永远 18 岁的技术宅</p>
</blockquote>
<hr>
<h1>1. 概述</h1>
<p><a href="https://github.com/Dromara/soul">Soul</a> 是基于 <a href="http://www.iocoder.cn/Spring-Boot/WebFlux/?self">WebFlux</a> 实现的<strong>响应式</strong>的 API 网关，具有异步、高性能、跨语言等特点。</p>
<blockquote>
<p>作者：我希望能够有一样东西像<strong>灵魂</strong>一样，保护您的微服务。在参考了 Kong、<a href="http://www.iocoder.cn/categories/Spring-Cloud-Gateway/?self">Spring Cloud Gateway</a> 等优秀的网关后，站在巨人的肩膀上，Soul 由此诞生！</p>
<p>作者是艿艿的大表弟，胖友信么？！</p>
</blockquote>
<p>目前 Soul 功能列表如下：</p>
<ul>
<li>
<p>支持各种语言，无缝集成到 Dubbo、Spring Cloud、Spring Boot 中。</p>
<blockquote>
<p>Soul 是极其少支持 Dubbo 的 API 网关，通过 <a href="http://www.iocoder.cn/Dubbo/good-collection/?self">Dubbo 泛化调用</a> 实现。</p>
</blockquote>
</li>
<li>
<p>支持各种语言(http协议)，支持 dubbo，springcloud协议。</p>
</li>
<li>
<p>插件化设计思想，插件热插拔,易扩展。</p>
</li>
<li>
<p>灵活的流量筛选，能满足各种流量控制。</p>
</li>
<li>
<p>内置丰富的插件支持，鉴权，限流，熔断，防火墙等等。</p>
</li>
<li>
<p>流量配置动态化，性能极高，网关消耗在 1~2ms。</p>
</li>
<li>
<p>支持集群部署，支持 A/B Test, 蓝绿发布。</p>
</li>
</ul>
<p>整体架构如下图所示：</p>
<p><img src="https://yu199195.github.io/images/soul/soul-framework.png" alt="架构图"></p>
<p>是不是看着就贼酷炫，实际一脸懵逼。不要慌~我们先来搭建 Soul 网关。</p>
<h1>2. 单机部署</h1>
<p>本小节，我们来单机部署一个 Soul 服务，适合<strong>测试</strong>环境。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/01.png" alt="Soul 单机部署"></p>
<h2>2.1 MySQL 安装</h2>
<p>相信大家都会，艿艿就不瞎哔哔了。嘿嘿~注意，目前最好安装 <strong>5.X</strong> 版本，艿艿一开始用 8.X 存在报错的情况。</p>
<p>安装完成后，创建 <code>soul</code> 数据库。</p>
<h2>2.2 Soul Admin 安装</h2>
<p><a href="https://dromara.org/zh-cn/docs/soul/admin.html">Soul Admin</a> <strong>控制台</strong>，负责所有流量的管理、<strong>配置</strong>等等，并提供给 <strong>网关服务</strong>读取。</p>
<blockquote>
<p>友情提示：后续推荐胖友阅读如下两篇文章，搞懂 Soul Admin 和 Soul Bootstrap 的同步的原理：</p>
<ul>
<li><a href="https://dromara.org/zh-cn/docs/soul/config.html">《Soul 文档 —— 数据配置流程》</a></li>
<li><a href="https://dromara.org/zh-cn/docs/soul/dataSync.html">《Soul 文档 —— 数据同步原理》</a></li>
</ul>
</blockquote>
<p>① 从 <a href="https://yu199195.github.io/jar/soul-admin.jar">https://yu199195.github.io/jar/soul-admin.jar</a> 下载<strong>启动 jar 包</strong>。</p>
<pre><code class="language-Bash"><span class="hljs-comment"># 创建目录</span>
$ mkdir -p /Users/yunai/Soul
$ <span class="hljs-built_in">cd</span> /Users/yunai/Soul

<span class="hljs-comment"># 下载</span>
$ wget  https://yu199195.github.io/jar/soul-admin.jar
</code></pre>
<p>② 通过 <code>java -jar soul-admin.jar</code> 命令启动 Soul Admin 控制台。完整命令如下：</p>
<pre><code class="language-Bash">$ java -jar soul-admin.jar --spring.datasource.url=<span class="hljs-string">"jdbc:mysql://s1.iocoder.cn:3306/soul?useUnicode=true&amp;characterEncoding=utf-8&amp;zeroDateTimeBehavior=CONVERT_TO_NULL&amp;failOverReadOnly=false&amp;autoReconnect=true&amp;useSSL=false"</span> --spring.datasource.username=<span class="hljs-string">'root'</span> --spring.datasource.password=<span class="hljs-string">'3WLiVUBEwTbvAfsh'</span>
</code></pre>
<ul>
<li><code>--spring.datasource.url</code> 配置项，修改成胖友的数据库<strong>地址</strong>。</li>
<li><code>--spring.datasource.username</code> 配置项，修改成胖友的数据库<strong>账号</strong>。</li>
<li><code>--spring.datasource.password</code> 配置项，修改成胖友的数据库<strong>密码</strong>。</li>
</ul>
<p>Soul Admin 会<strong>自动</strong>创建数据库，以及表结构，并初始化默认数据。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/11.png" alt=" 数据库"></p>
<blockquote>
<p>友情提示：具体的数据库设计，后续可以看看<a href="https://dromara.org/zh-cn/docs/soul/db.html">《Soul 文档 —— 数据库设计》</a>。</p>
</blockquote>
<p>③ 启动完成后，我们可以通过日志看到 Soul Admin 启动在 <strong>9095</strong> 端口。使用浏览器，访问 <a href="http://127.0.0.1:9095/">http://127.0.0.1:9095/</a> 地址，进入登录页。</p>
<p><img src="http://www.iocoder.cn/images/Soul/12.png" alt="Soul Admin - 登录页"></p>
<p>默认内置管理员账号「<strong>admin/123456</strong>」。输入账号密码，进入首页。</p>
<p><img src="http://www.iocoder.cn/images/Soul/13.png" alt="Soul Admin - 首页"></p>
<p>胖友可以自己随便点点，简单了解下有哪些功能。</p>
<h2>搭建自己的网关（推荐）</h2>
<ul>
<li>
<p>首先你新建一个空的springboot项目，可以参考 soul-bootstrap. 也可以在spring官网:[<a href="https://spring.io/quickstart">https://spring.io/quickstart</a>]</p>
</li>
<li>
<p>引入如下jar包：</p>
</li>
</ul>
<pre><code class="language-xml">  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-webflux<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.2.2.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-actuator<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.2.2.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

  <span class="hljs-comment">&lt;!--soul gateway start--&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-gateway<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

   <span class="hljs-comment">&lt;!--soul data sync start use websocket--&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-sync-data-websocket<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<ul>
<li>在你的 <code>application.yaml</code> 文件中加上如下配置：</li>
</ul>
<pre><code class="language-yaml"><span class="hljs-attr">spring:</span>
   <span class="hljs-attr">main:</span>
     <span class="hljs-attr">allow-bean-definition-overriding:</span> <span class="hljs-literal">true</span>

<span class="hljs-attr">management:</span>
  <span class="hljs-attr">health:</span>
    <span class="hljs-attr">defaults:</span>
      <span class="hljs-attr">enabled:</span> <span class="hljs-literal">false</span>
<span class="hljs-attr">soul :</span>
    <span class="hljs-attr">sync:</span>
        <span class="hljs-attr">websocket :</span>
             <span class="hljs-attr">urls:</span> <span class="hljs-string">ws://localhost:9095/websocket</span>  <span class="hljs-string">//设置成你的soul-admin地址</span>
</code></pre>
<ul>
<li>你的项目环境搭建完成,启动你的项目。</li>
</ul>
<h2>2.4 下一步</h2>
<p>至此，我们已经完成了 Soul 服务的单机部署，是不是挺简单的。下面，胖友可以根据自己的需要，阅读如下小节：</p>
<ul>
<li><a href="#">「3. 接入 Dubbo 应用」</a></li>
<li><a href="#">「4. 接入 Spring Boot 应用」</a></li>
<li><a href="#">「5. 接入 Spring Cloud 应用」</a></li>
</ul>
<h1>3. 接入 Dubbo 应用</h1>
<blockquote>
<p>示例代码对应仓库：<a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service/"><code>lab-60-soul-dubbo-demo-user-service</code></a></p>
</blockquote>
<p>本小节，我们参考<a href="https://dromara.org/zh-cn/docs/soul/user-dubbo.html">《Soul 文档 —— Dubbo 用户接入》</a>文章，接入 Soul 服务网关。整个示例架构如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/21.png" alt="示例的整体架构"></p>
<p>下面，我们来开始正式接入 Dubbo 应用。</p>
<h2>3.1 设置 dubbo 插件</h2>
<p>先需要设置 <a href="https://dromara.org/zh-cn/docs/soul/plugin-dubbo.html">dubbo 插件</a> 的<strong>注册中心</strong>，因为 Soul Bootstrap 服务网关需要从<strong>注册中心</strong>获取到 Dubbo 服务的实例列表。</p>
<p>① 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/plugin">http://127.0.0.1:9095/#/system/plugin</a> 地址，进入「系统管理 -&gt; 插件管理」菜单，可以看到 dubbo 插件。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/22.png" alt="系统管理 -&gt; 插件管理"></p>
<p>② 点击 dubbo 插件的「编辑」按钮，设置注册中心的配置。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/23.png" alt="系统管理 -&gt; 插件管理 -&gt; 编辑"></p>
<ul>
<li>因为我们将使用 <a href="http://www.iocoder.cn/Nacos/install/?self">Nacos</a> 作为 Dubbo 服务的注册中心，所以这里设置为 <code>{&quot;register&quot;:&quot;nacos://localhost:8848&quot;}</code>。</li>
<li>如果胖友使用 <a href="http://www.iocoder.cn/Zookeeper/install/?self">Zookeeper</a> 作为 Dubbo 服务的注册中心，所以这里设置为 <code>{&quot;register&quot;:&quot;zookeeper://localhost:2181&quot;}</code>。</li>
</ul>
<blockquote>
<p>友情提示：注册中心的地址，记得要填写正确哈~</p>
</blockquote>
<p>③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的<strong>自动加载</strong>，所以我们此时需要<strong>手动重启</strong>下。</p>
<h2>3.2 在网关的pom.xml引入对 dubbo插件的依赖</h2>
<pre><code class="language-xml">
<span class="hljs-comment">&lt;!--soul apache dubbo plugin start--&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-apache-dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
 <span class="hljs-comment">&lt;!--soul apache dubbo plugin end--&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.7.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-comment">&lt;!-- Dubbo Nacos registry dependency start --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.apache.dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>dubbo-registry-nacos<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.7.5<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba.nacos<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>nacos-client<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.1.4<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-comment">&lt;!-- Dubbo Nacos registry dependency  end--&gt;</span>

</code></pre>
<h2>3.3 搭建 Dubbo 示例项目</h2>
<p>先快速搭建一个 Dubbo 示例项目，暂未接入 Soul 网关。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/24.png" alt="项目结构"></p>
<ul>
<li><a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service-api/"><code>lab-60-soul-dubbo-demo-user-service-api</code></a></li>
<li><a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service/"><code>lab-60-soul-dubbo-demo-user-service</code></a></li>
</ul>
<blockquote>
<p>友情提示：如果胖友对 Dubbo + Nacos 不了解的胖友，可以阅读<a href="http://www.iocoder.cn/Spring-Boot/Dubbo/?self">《芋道 Spring Boot Dubbo 入门》</a>文章。</p>
</blockquote>
<p>下面，我们来将它改造接入 Soul 网关。</p>
<h3>3.2.1 引入依赖</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service/pom.xml"><code>pom.xml</code></a> 文件，引入 <a href="https://mvnrepository.com/artifact/org.dromara/soul-client-apache-dubbo"><code>soul-client-apache-dubbo</code></a> 依赖，它是 Soul 对 Apache Dubbo <strong>2.7.X</strong> 的集成支持。</p>
<pre><code class="language-XML"><span class="hljs-comment">&lt;!-- 引入 Soul 针对 Dubbo 的集成的依赖 --&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-client-apache-dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<blockquote>
<p>友情提示：如果胖友使用 Alibaba Dubbo <strong>2.6.X</strong> 的话,依赖如下：</p>
</blockquote>
<pre><code class="language-XML"><span class="hljs-comment">&lt;!-- 引入 Soul 针对 Dubbo 的集成的依赖 --&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-client-alibaba-dubbo<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<h3>3.2.2 配置文件</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service/src/main/resources/application.yaml"><code>application.yaml</code></a> 配置文件，添加 Soul 配置项如下：</p>
<pre><code class="language-YAML"><span class="hljs-attr">soul:</span>
  <span class="hljs-comment"># Soul 针对 Dubbo 的配置项，对应 DubboConfig 配置类</span>
  <span class="hljs-attr">dubbo:</span>
    <span class="hljs-attr">admin-url:</span> <span class="hljs-string">http://127.0.0.1:9095</span> <span class="hljs-comment"># Soul Admin 地址</span>
    <span class="hljs-attr">context-path:</span> <span class="hljs-string">/user-api</span> <span class="hljs-comment"># 设置在 Soul 网关的路由前缀，例如说 /order、/product 等等。</span>
                            <span class="hljs-comment"># 后续，网关会根据该 context-path 来进行路由</span>
    <span class="hljs-attr">app-name:</span> <span class="hljs-string">user-service</span> <span class="hljs-comment"># 应用名。未配置情况下，默认使用 Dubbo 的应用名</span>
</code></pre>
<p><code>soul.dubbo</code> 配置项，Soul 对 Dubbo 的配置项，对应 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-dubbo/soul-client-dubbo-common/src/main/java/org/dromara/soul/client/dubbo/common/config/DubboConfig.java">DubboConfig</a> 配置类。具体每个配置项的作用，胖友自己看配置项后的注释。</p>
<h3>3.2.3 UserServiceImpl</h3>
<p>需要在 Dubbo Service <strong>实现类</strong>的<strong>方法上</strong>，添加 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-dubbo/soul-client-dubbo-common/src/main/java/org/dromara/soul/client/dubbo/common/annotation/SoulDubboClient.java"><code>@SoulDubboClient</code></a> 注解，用于设置每个 Dubbo 方法对应的<strong>请求路径</strong>。这里，我们修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-dubbo-demo/lab-60-soul-dubbo-demo-user-service/src/main/java/cn/iocoder/springboot/lab60/userservice/service/UserServiceImpl.java">UserServiceImpl</a> 类，添加该注解。代码如下：</p>
<pre><code class="language-Java"><span class="hljs-meta">@org</span>.apache.dubbo.config.annotation.Service(version = <span class="hljs-string">"1.0.0"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserServiceImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">UserService</span> </span>{

    <span class="hljs-keyword">private</span> Logger logger = LoggerFactory.getLogger(getClass());

    <span class="hljs-meta">@Override</span>
    <span class="hljs-meta">@SoulDubboClient</span>(path = <span class="hljs-string">"/user/get"</span>, desc = <span class="hljs-string">"获得用户详细"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getUser</span><span class="hljs-params">(Integer id)</span> </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"User:"</span> + id;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-meta">@SoulDubboClient</span>(path = <span class="hljs-string">"/user/create"</span>, desc = <span class="hljs-string">"创建用户"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">createUser</span><span class="hljs-params">(UserCreateDTO createDTO)</span> </span>{
        logger.info(<span class="hljs-string">"[createUser][username({}) password({})]"</span>, createDTO.getNickname(), createDTO.getGender());
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

}
</code></pre>
<p><code>@SoulDubboClient</code> 注解一共有三个属性：</p>
<ul>
<li><code>path</code>：映射的 HTTP 接口的请求路径。</li>
<li><code>desc</code>：接口的描述，便于知道其用途。</li>
<li><code>enable</code>：是否开启，默认为 <code>true</code> 开启。</li>
</ul>
<p>后续，在 Dubbo 服务启动时，SoulDubboClient 会自动<a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-alibaba-dubbo/src/main/java/org/dromara/soul/client/dubbo/spring/DubboServiceBeanPostProcessor.java">解析</a> <code>@SoulDubboClient</code> 注解的 Dubbo 方法，写入方法的<strong>元数据</strong>到 Soul Admin 控制台，最终通知到 Soul Bootstrap 服务网关上。</p>
<h2>3.3 简单测试</h2>
<p>① 执行 UserServiceApplication 启动 Dubbo 服务。在 IDEA 控制台可以看到如下日志，看到写入 Dubbo 方法的<strong>元数据</strong>到 Soul Admin 控制台。</p>
<pre><code class="language-Java"><span class="hljs-number">2020</span>-<span class="hljs-number">05</span>-<span class="hljs-number">23</span> <span class="hljs-number">01</span>:<span class="hljs-number">27</span>:<span class="hljs-number">56.682</span>  INFO <span class="hljs-number">54370</span> --- [pool-<span class="hljs-number">2</span>-thread-<span class="hljs-number">1</span>] .d.s.c.d.s.DubboServiceBeanPostProcessor : dubbo client register success :{} {<span class="hljs-string">"appName"</span>:<span class="hljs-string">"user-service"</span>,<span class="hljs-string">"path"</span>:<span class="hljs-string">"/user-api/user/get"</span>,<span class="hljs-string">"pathDesc"</span>:<span class="hljs-string">"获得用户详细"</span>,<span class="hljs-string">"rpcType"</span>:<span class="hljs-string">"dubbo"</span>,<span class="hljs-string">"serviceName"</span>:<span class="hljs-string">"cn.iocoder.springboot.lab60.userservice.api.UserService"</span>,<span class="hljs-string">"methodName"</span>:<span class="hljs-string">"getUser"</span>,<span class="hljs-string">"parameterTypes"</span>:<span class="hljs-string">"java.lang.Integer"</span>,<span class="hljs-string">"rpcExt"</span>:<span class="hljs-string">"{\"version\":\"1.0.0\"}"</span>,<span class="hljs-string">"enabled"</span>:<span class="hljs-keyword">true</span>}
<span class="hljs-number">2020</span>-<span class="hljs-number">05</span>-<span class="hljs-number">23</span> <span class="hljs-number">01</span>:<span class="hljs-number">27</span>:<span class="hljs-number">56.944</span>  INFO <span class="hljs-number">54370</span> --- [pool-<span class="hljs-number">2</span>-thread-<span class="hljs-number">1</span>] .d.s.c.d.s.DubboServiceBeanPostProcessor : dubbo client register success :{} {<span class="hljs-string">"appName"</span>:<span class="hljs-string">"user-service"</span>,<span class="hljs-string">"path"</span>:<span class="hljs-string">"/user-api/user/create"</span>,<span class="hljs-string">"pathDesc"</span>:<span class="hljs-string">"创建用户"</span>,<span class="hljs-string">"rpcType"</span>:<span class="hljs-string">"dubbo"</span>,<span class="hljs-string">"serviceName"</span>:<span class="hljs-string">"cn.iocoder.springboot.lab60.userservice.api.UserService"</span>,<span class="hljs-string">"methodName"</span>:<span class="hljs-string">"createUser"</span>,<span class="hljs-string">"parameterTypes"</span>:<span class="hljs-string">"cn.iocoder.springboot.lab60.userservice.api.dto.UserCreateDTO"</span>,<span class="hljs-string">"rpcExt"</span>:<span class="hljs-string">"{\"version\":\"1.0.0\"}"</span>,<span class="hljs-string">"enabled"</span>:<span class="hljs-keyword">true</span>}
</code></pre>
<p>② 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/metadata">http://127.0.0.1:9095/#/system/metadata</a> 地址，进入「系统管理 -&gt; 元数据」菜单，可以看到上述注册的元数据。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/25.png" alt="系统管理 -&gt; 元数据"></p>
<p>③ 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/plug/dubbo">http://127.0.0.1:9095/#/plug/dubbo</a> 地址，进入「插件列表 -&gt; Dubbo」菜单，看到<strong>选择器</strong>和<strong>规则</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/26.png" alt="插件列表 -&gt; Dubbo"></p>
<p>点击<strong>选择器</strong> <code>/user-api</code> 的「编辑」按钮，查看该选择器的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/27.png" alt="插件列表 -&gt; Dubbo -&gt; 选择器"></p>
<p>点击<strong>规则</strong> <code>/user-api/user/get</code> 的「编辑」按钮，查看该规则的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/28.png" alt="插件列表 -&gt; Dubbo -&gt; 规则"></p>
<p>④ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/user-api/user/get">http://127.0.0.1:9195/user-api/user/get</a> 地址，调用 <code>UserServiceImpl#getUser(Integer id)</code> 方法。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/29.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>POST</code>。</li>
<li>请求内容类型为 <code>application/json</code>。</li>
<li>因为 <code>UserServiceImpl#getUser(Integer id)</code> 方法是<strong>非 Bean</strong> 参数类型，所以直接在 Request <strong>Body</strong> 输入具体值即可。</li>
</ul>
<p>⑤ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/user-api/user/create">http://127.0.0.1:9195/user-api/user/create</a> 地址，调用 <code>UserServiceImpl#createUser(UserCreateDTO createDTO)</code> 方法。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/30.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>POST</code>。</li>
<li>请求内容类型为 <code>application/json</code>。</li>
<li>因为 <code>UserServiceImpl#createUser(UserCreateDTO createDTO)</code> 方法是 <strong>Bean</strong> 参数类型，所以直接在 Request <strong>Body</strong> 输入 JSON 数据格式。</li>
</ul>
<p>至此，我们已经完成了 Soul 网关接入 Dubbo 应用，并进行相应的而测试。</p>
<blockquote>
<p>友情提示：实际上，我们<strong>也</strong>可以参考<a href="https://dromara.org/zh-cn/docs/soul/plugin-dubbo.html">《Soul 文档 —— dubbo 插件》</a>，<strong>手动</strong>在 Soul Admin 控制台配置 Dubbo 接口方法的<strong>元数据</strong>，以及进行 dubbo 插件的<strong>选择器</strong>和<strong>规则</strong>的设置，实现 Soul Bootstrap 服务网关转发请求到 Dubbo 服务，<strong>无需</strong>在 Dubbo 项目中引入 <code>soul-client-apache-dubbo</code> 依赖。</p>
<p>也就是说，引入 <code>soul-spring-boot-starter-client-apache-dubbo</code> 依赖的目的，是为了实现<strong>自动化</strong>，毕竟<strong>手工</strong>配置比较麻烦，并且容易出错。</p>
</blockquote>
<h1>4. 接入 Spring Boot 应用</h1>
<ul>
<li>在网关的pom.xml引入依赖</li>
</ul>
<pre><code class="language-xml">  <span class="hljs-comment">&lt;!--if you use http proxy start this--&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-divide<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

   <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-httpclient<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<blockquote>
<p>示例代码对应仓库：<a href="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-60/lab-60-soul-spring-boot-demo"><code>lab-60-soul-spring-boot-demo</code></a></p>
</blockquote>
<p>本小节，我们参考<a href="https://dromara.org/zh-cn/docs/soul/user-http.html">《Soul 文档 —— http 用户接入》</a>文章，接入 Soul 服务网关。整个示例架构如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/40.png" alt="示例的整体架构"></p>
<p>下面，我们来开始正式接入 Spring Boot 应用。</p>
<h2>4.1 设置 divide 插件</h2>
<p>需要设置 <a href="https://dromara.org/zh-cn/docs/soul/plugin-divide.html">divide 插件</a> 为<strong>开启</strong>。该插件实现 HTTP <strong>正向</strong>代理的功能，所有 HTTP 类型的请求你，都由它进行<strong>负载均衡</strong>的调用。</p>
<p>使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/plugin">http://127.0.0.1:9095/#/system/plugin</a> 地址，进入「系统管理 -&gt; 插件管理」菜单，可以看到 divide 插件。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/41.png" alt="系统管理 -&gt; 插件管理"></p>
<p>默认情况下，divide 插件已经是<strong>开启</strong>状态，所以无需开启。</p>
<h2>4.2 搭建 Spring Boot 示例项目</h2>
<p>先快速搭建一个 Spring Boot 示例项目，暂未接入 Soul 网关。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/42.png" alt="项目结构"></p>
<ul>
<li><a href="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-60/lab-60-soul-spring-boot-demo"><code>lab-60-soul-spring-boot-demo</code></a></li>
</ul>
<h3>4.3.1 引入依赖</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-spring-boot-demo/pom.xml"><code>pom.xml</code></a> 文件，引入 <a href="https://mvnrepository.com/artifact/org.dromara/soul-client-springmvc"><code>soul-client-springmvc</code></a> 依赖，它是 Soul 对 SpringMVC 的集成支持。</p>
<pre><code class="language-xml">     <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-client-springmvc<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<h3>4.3.2 配置文件</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-spring-boot-demo/src/main/resources/application.yaml"><code>application.yaml</code></a> 配置文件，添加 Soul 配置项如下：</p>
<pre><code class="language-YAML"><span class="hljs-attr">soul:</span>
  <span class="hljs-comment"># Soul 针对 SpringMVC 的配置项，对应 SoulHttpConfig 配置类</span>
  <span class="hljs-attr">http:</span>
    <span class="hljs-attr">admin-url:</span> <span class="hljs-string">http://127.0.0.1:9095</span> <span class="hljs-comment"># Soul Admin 地址</span>
    <span class="hljs-attr">context-path:</span> <span class="hljs-string">/sb-demo-api</span> <span class="hljs-comment"># 设置在 Soul 网关的路由前缀，例如说 /order、/product 等等。</span>
                               <span class="hljs-comment"># 后续，网关会根据该 context-path 来进行路由</span>
    <span class="hljs-attr">app-name:</span> <span class="hljs-string">sb-demo-service</span> <span class="hljs-comment"># 应用名。未配置情况下，默认使用 `spring.application.name` 配置项</span>
    <span class="hljs-attr">port:</span> <span class="hljs-number">8080</span> <span class="hljs-comment">#你本项目的启动端口</span>
    <span class="hljs-attr">full:</span> <span class="hljs-literal">false</span>   <span class="hljs-comment"># 设置true 代表代理你的整个服务，false表示代理你其中某几个controller</span>
</code></pre>
<p><code>soul.http</code> 配置项，Soul 对 SpringMVC 的配置项，对应 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springmvc/src/main/java/org/dromara/soul/client/springmvc/config/SoulSpringMvcConfig.java">SoulSpringMvcConfig</a> 配置类。具体每个配置项的作用，胖友自己看配置项后的注释。</p>
<h3>4.3.3 UserController</h3>
<p>需要在 Controller 的 <strong>HTTP API 方法上</strong>，添加 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springmvc/src/main/java/org/dromara/soul/client/springmvc/annotation/SoulSpringMvcClient.java"><code>@SoulSpringMvcClient</code></a> 注解，用于设置每个 API 方法对应的<strong>请求路径</strong>。这里，我们修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-spring-boot-demo/src/main/java/cn/iocoder/springboot/lab60/controller/UserController.java">UserController</a> 类，添加该注解。代码如下：</p>
<pre><code class="language-Java"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping</span>(<span class="hljs-string">"/user"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserController</span> </span>{

    <span class="hljs-keyword">private</span> Logger logger = LoggerFactory.getLogger(getClass());

    <span class="hljs-meta">@GetMapping</span>(<span class="hljs-string">"/get"</span>)
    <span class="hljs-meta">@SoulSpringMvcClient</span>(path = <span class="hljs-string">"/user/get"</span>, desc = <span class="hljs-string">"获得用户详细"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getUser</span><span class="hljs-params">(@RequestParam(<span class="hljs-string">"id"</span>)</span> Integer id) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"DEMO:"</span> + id;
    }

    <span class="hljs-meta">@PostMapping</span>(<span class="hljs-string">"/create"</span>)
    <span class="hljs-meta">@SoulSpringMvcClient</span>(path = <span class="hljs-string">"/user/create"</span>, desc = <span class="hljs-string">"创建用户"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">createUser</span><span class="hljs-params">(@RequestBody UserCreateDTO createDTO)</span> </span>{
        logger.info(<span class="hljs-string">"[createUser][username({}) password({})]"</span>, createDTO.getNickname(), createDTO.getGender());
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

}
</code></pre>
<p><code>@SoulSpringMvcClient</code> 注解一共有三个属性：</p>
<ul>
<li><code>path</code>：映射的 HTTP 接口的请求路径。</li>
<li><code>desc</code>：接口的描述，便于知道其用途。</li>
<li><code>enable</code>：是否开启，默认为 <code>true</code> 开启。</li>
</ul>
<p>后续，在 Spring Boot 应用启动时，SoulSpringMvcClient 会自动<a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springmvc/src/main/java/org/dromara/soul/client/springmvc/init/SpringMvcClientBeanPostProcessor.java">解析</a> <code>@SoulSpringMvcClien</code> 注解的 API 方法，写入方法的<strong>元数据</strong>到 Soul Admin 控制台，最终通知到 Soul Bootstrap 服务网关上。</p>
<h2>4.4 简单测试</h2>
<p>① 执行 DemoApplication 启动 Spring Boot 应用。在 IDEA 控制台可以看到如下日志，看到写入 HTTP API 方法的<strong>元数据</strong>到 Soul Admin 控制台。</p>
<p>③ 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/plug/divide">http://127.0.0.1:9095/#/plug/divide</a> 地址，进入「插件列表 -&gt; Divide」菜单，看到<strong>选择器</strong>和<strong>规则</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/44.png" alt="插件列表 -&gt; Divide"></p>
<p>点击<strong>选择器</strong> <code>/sb-demo-api</code> 的「编辑」按钮，查看该选择器的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/45.png" alt="插件列表 -&gt; Divide -&gt; 选择器"></p>
<p>点击<strong>规则</strong> <code>/sb-demo-api/user/get</code> 的「编辑」按钮，查看该规则的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/46.png" alt="插件列表 -&gt; Divide -&gt; 规则"></p>
<p>④ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/sb-demo-api/user/get?id=1">http://127.0.0.1:9195/sb-demo-api/user/get?id=1</a> 地址，转发到 <code>GET /user/get</code> 接口上。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/47.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>GET</code>。</li>
<li>请求参数，直接带在 URL 后面。</li>
</ul>
<p>⑤ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/sb-demo-api/user/create">http://127.0.0.1:9195/sb-demo-api/user/create</a> 地址，转发到 <code>POST /user/create</code> 接口上。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/48.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>POST</code>。</li>
<li>请求内容类型为 <code>application/json</code>。</li>
<li>因为 <code>POST /user/create</code> 使用 JSON 接参，所以直接在 Request <strong>Body</strong> 输入 JSON 数据格式。</li>
</ul>
<p>至此，我们已经完成了 Soul 网关接入 Spring Boot 应用，并进行相应的而测试。</p>
<blockquote>
<p>友情提示：实际上，我们<strong>也</strong>可以参考<a href="https://dromara.org/zh-cn/docs/soul/plugin-divide.html">《Soul 文档 —— divide 插件》</a>，<strong>手动</strong>在 Soul Admin 控制台配置 API 接口方法的<strong>元数据</strong>，以及进行 divide 插件的<strong>选择器</strong>和<strong>规则</strong>的设置，实现 Soul Bootstrap 服务网关转发请求到 Spring Boot 应用，<strong>无需</strong>在 Spring Boot 应用中引入 <code>soul-client-springmvc</code> 依赖。</p>
<p>也就是说，引入 <code>soul-spring-boot-starter-client-springmvc</code> 依赖的目的，是为了实现<strong>自动化</strong>，毕竟<strong>手工</strong>配置比较麻烦，并且容易出错。</p>
</blockquote>
<h1>5. 接入 Spring Cloud 应用</h1>
<blockquote>
<p>示例代码对应仓库：<a href="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-60/lab-60-soul-spring-cloud-demo"><code>lab-60-soul-spring-cloud-demo</code></a></p>
</blockquote>
<p>本小节，我们参考<a href="https://dromara.org/zh-cn/docs/soul/user-springcloud.html">《Soul 文档 —— springcloud 用户接入》</a>文章，接入 Soul 服务网关。整个示例架构如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/50.png" alt="示例的整体架构"></p>
<p>下面，我们来开始正式接入 Spring Cloud 应用。</p>
<h2>5.1 设置 springcloud 插件</h2>
<p>需要设置 <a href="https://dromara.org/zh-cn/docs/soul/plugin-springcloud.html">springcloud 插件</a> 为<strong>开启</strong>。该插件实现从 Spring Cloud 注册中心获取服务的示例列表，后续使用 <a href="http://www.iocoder.cn/Spring-Cloud-Netflix/Ribbon/?self">Ribbon</a> 实现<strong>负载均衡</strong>的调用。</p>
<p>使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/plugin">http://127.0.0.1:9095/#/system/plugin</a> 地址，进入「系统管理 -&gt; 插件管理」菜单，可以看到 springcloud 插件。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/51.png" alt="系统管理 -&gt; 插件管理"></p>
<p>默认情况下，springcloud 插件已经是<strong>开启</strong>状态，所以无需开启。</p>
<h2>5.2 安装 Nacos</h2>
<p>我们使用 Nacos 作为 Spring Cloud 应用的注册中心，所有胖友可以参照<a href="http://www.iocoder.cn/Nacos/install/?self">《Nacos 极简入门》</a>文章，搭建一个 Nacos 注册中心。</p>
<blockquote>
<p>友情提示：如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友，可以参照<a href="http://www.iocoder.cn/Spring-Cloud/Netflix-Eureka/?self">《芋道 Spring Cloud Netflix 注册中心 Eureka 入门》</a>文章，搭建一个 Eureka 注册中心。</p>
</blockquote>
<h2>5.3 在网关的pom.xml引入依赖</h2>
<p>因为 Soul Bootstrap 需要从注册中心获取 Spring Cloud 应用的实例列表，所以需要集成 Spring Cloud 注册中心。目前，<strong>默认</strong>情况下 Soul Bootstrap 网关服务提供的 <code>soul-bootstrap.jar</code> 包，并未引入相关依赖，所以我们需要<strong>自己</strong>修改源码，并进行打包。</p>
<pre><code class="language-xml">  <span class="hljs-comment">&lt;!--soul springCloud plugin start--&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-plugin-springcloud<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
   <span class="hljs-comment">&lt;!--soul springCloud plugin end--&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.alibaba.cloud<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-cloud-starter-alibaba-nacos-discovery<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.1.0.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.cloud<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-cloud-commons<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.2.0.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.cloud<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-cloud-starter-netflix-ribbon<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.2.0.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<ul>
<li>在网关的yml文件中 新增如下配置:</li>
</ul>
<pre><code class="language-yaml">  <span class="hljs-attr">spring:</span>
     <span class="hljs-attr">cloud:</span>
       <span class="hljs-attr">nacos:</span>
         <span class="hljs-attr">discovery:</span>
            <span class="hljs-attr">server-addr:</span> <span class="hljs-number">127.0</span><span class="hljs-number">.0</span><span class="hljs-number">.1</span><span class="hljs-string">:8848</span> <span class="hljs-comment"># 你的nacos地址</span>
</code></pre>
<blockquote>
<p>友情提示：如果想要 Eureka 作为 Spring Cloud 应用注册中心的胖友，也是修改配置文件，和引入依赖。</p>
</blockquote>
<p>④  启动的服务网关，美滋滋~</p>
<blockquote>
<p>友情提示：启动时，会报 <code>Connection refused: localhost/127.0.0.1:6379</code> 错误，这是 Soul 限流功能需要使用到 Redis，可以暂时忽略。</p>
</blockquote>
<h2>5.4 搭建 Spring Cloud 示例项目</h2>
<p>先快速搭建一个 Spring Cloud 示例项目，暂未接入 Soul 网关。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/52.png" alt="项目结构"></p>
<ul>
<li><a href="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-60/lab-60-soul-spring-cloud-demo"><code>lab-60-soul-spring-cloud-demo</code></a></li>
</ul>
<h3>5.4.1 引入依赖</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/tree/master/lab-60/lab-60-soul-spring-cloud-demo/pom.xml"><code>pom.xml</code></a> 文件，引入 <a href="https://mvnrepository.com/artifact/org.dromara/soul-client-springcloud"><code>soul-client-springcloud</code></a> 依赖，它是 Soul 对 Spring Cloud 的集成支持。</p>
<pre><code class="language-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.dromara<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>soul-spring-boot-starter-client-springcloud<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>${last.version}<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
</code></pre>
<h3>5.4.2 配置文件</h3>
<p>修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-spring-cloud-demo/src/main/resources/application.yaml"><code>application.yaml</code></a> 配置文件，添加 Soul 配置项如下：</p>
<pre><code class="language-YAML"><span class="hljs-attr">soul:</span>
  <span class="hljs-comment"># Soul 针对 SpringMVC 的配置项，对应 SoulSpringCloudConfig 配置类</span>
  <span class="hljs-attr">springcloud:</span>
    <span class="hljs-attr">admin-url:</span> <span class="hljs-string">http://127.0.0.1:9095</span> <span class="hljs-comment"># Soul Admin 地址</span>
    <span class="hljs-attr">context-path:</span> <span class="hljs-string">/sc-user-service-api</span> <span class="hljs-comment"># 设置在 Soul 网关的路由前缀，例如说 /order、/product 等等。</span>
                               <span class="hljs-comment"># 后续，网关会根据该 context-path 来进行路由</span>
    <span class="hljs-attr">app-name:</span> <span class="hljs-string">sc-user-service</span> <span class="hljs-comment"># 应用名。未配置情况下，默认使用 `spring.application.name` 配置项</span>
</code></pre>
<p><code>soul.springcloud</code> 配置项，Soul 对 Spring Cloud 的配置项，对应 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springcloud/src/main/java/org/dromara/soul/client/springcloud/config/SoulSpringCloudConfig.java">SoulSpringCloudConfig</a> 配置类。具体每个配置项的作用，胖友自己看配置项后的注释。</p>
<h3>5.4.3 UserController</h3>
<p>需要在 Controller 的 <strong>HTTP API 方法上</strong>，添加 <a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springcloud/src/main/java/org/dromara/soul/client/springcloud/annotation/SoulSpringCloudClient.java"><code>@SoulSpringCloudClient</code></a> 注解，用于设置每个 API 方法对应的<strong>请求路径</strong>。这里，我们修改 <a href="https://github.com/YunaiV/SpringBoot-Labs/blob/master/lab-60/lab-60-soul-spring-cloud-demo/src/main/java/cn/iocoder/springboot/lab60/controller/UserController.java">UserController</a> 类，添加该注解。代码如下：</p>
<pre><code class="language-Java"><span class="hljs-meta">@RestController</span>
<span class="hljs-meta">@RequestMapping</span>(<span class="hljs-string">"/user"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">UserController</span> </span>{

    <span class="hljs-keyword">private</span> Logger logger = LoggerFactory.getLogger(getClass());

    <span class="hljs-meta">@GetMapping</span>(<span class="hljs-string">"/get"</span>)
    <span class="hljs-meta">@SoulSpringCloudClient</span>(path = <span class="hljs-string">"/user/get"</span>, desc = <span class="hljs-string">"获得用户详细"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getUser</span><span class="hljs-params">(@RequestParam(<span class="hljs-string">"id"</span>)</span> Integer id) </span>{
        <span class="hljs-keyword">return</span> <span class="hljs-string">"DEMO:"</span> + id;
    }

    <span class="hljs-meta">@PostMapping</span>(<span class="hljs-string">"/create"</span>)
    <span class="hljs-meta">@SoulSpringCloudClient</span>(path = <span class="hljs-string">"/user/create"</span>, desc = <span class="hljs-string">"创建用户"</span>)
    <span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">createUser</span><span class="hljs-params">(@RequestBody UserCreateDTO createDTO)</span> </span>{
        logger.info(<span class="hljs-string">"[createUser][username({}) password({})]"</span>, createDTO.getNickname(), createDTO.getGender());
        <span class="hljs-keyword">return</span> <span class="hljs-number">1</span>;
    }

}
</code></pre>
<p><code>@SoulSpringCloudClient</code> 注解一共有三个属性：</p>
<ul>
<li><code>path</code>：映射的 HTTP 接口的请求路径。</li>
<li><code>desc</code>：接口的描述，便于知道其用途。</li>
<li><code>enable</code>：是否开启，默认为 <code>true</code> 开启。</li>
</ul>
<p>后续，在 Spring Cloud 应用启动时，SoulSpringCloudClient 会自动<a href="https://github.com/Dromara/soul/blob/master/soul-client/soul-client-http/soul-client-springcloud/src/main/java/org/dromara/soul/client/springcloud/init/SpringCloudClientBeanPostProcessor.java">解析</a> <code>@SoulSpringCloudClient</code> 注解的 API 方法，写入方法的<strong>元数据</strong>到 Soul Admin 控制台，最终通知到 Soul Bootstrap 服务网关上。</p>
<h2>5.5 简单测试</h2>
<p>① 执行 DemoApplication 启动 Spring Boot 应用。在 IDEA 控制台可以看到如下日志，看到写入 HTTP API 方法的<strong>元数据</strong>到 Soul Admin 控制台。</p>
<pre><code class="language-Java"><span class="hljs-number">2020</span>-<span class="hljs-number">05</span>-<span class="hljs-number">23</span> <span class="hljs-number">17</span>:<span class="hljs-number">00</span>:<span class="hljs-number">26.711</span>  INFO <span class="hljs-number">67422</span> --- [pool-<span class="hljs-number">1</span>-thread-<span class="hljs-number">1</span>] s.SoulSpringCloudClientBeanPostProcessor : springCloud client register success :{} {<span class="hljs-string">"appName"</span>:<span class="hljs-string">"sc-user-service"</span>,<span class="hljs-string">"path"</span>:<span class="hljs-string">"/sc-user-service-api/user/get"</span>,<span class="hljs-string">"pathDesc"</span>:<span class="hljs-string">"获得用户详细"</span>,<span class="hljs-string">"rpcType"</span>:<span class="hljs-string">"springCloud"</span>,<span class="hljs-string">"serviceName"</span>:<span class="hljs-string">"UserController"</span>,<span class="hljs-string">"methodName"</span>:<span class="hljs-string">"getUser"</span>,<span class="hljs-string">"parameterTypes"</span>:<span class="hljs-string">"java.lang.Integer"</span>,<span class="hljs-string">"rpcExt"</span>:<span class="hljs-string">""</span>,<span class="hljs-string">"enabled"</span>:<span class="hljs-keyword">true</span>}
<span class="hljs-number">2020</span>-<span class="hljs-number">05</span>-<span class="hljs-number">23</span> <span class="hljs-number">17</span>:<span class="hljs-number">00</span>:<span class="hljs-number">27.110</span>  INFO <span class="hljs-number">67422</span> --- [pool-<span class="hljs-number">1</span>-thread-<span class="hljs-number">1</span>] s.SoulSpringCloudClientBeanPostProcessor : springCloud client register success :{} {<span class="hljs-string">"appName"</span>:<span class="hljs-string">"sc-user-service"</span>,<span class="hljs-string">"path"</span>:<span class="hljs-string">"/sc-user-service-api/user/create"</span>,<span class="hljs-string">"pathDesc"</span>:<span class="hljs-string">"创建用户"</span>,<span class="hljs-string">"rpcType"</span>:<span class="hljs-string">"springCloud"</span>,<span class="hljs-string">"serviceName"</span>:<span class="hljs-string">"UserController"</span>,<span class="hljs-string">"methodName"</span>:<span class="hljs-string">"createUser"</span>,<span class="hljs-string">"parameterTypes"</span>:<span class="hljs-string">"cn.iocoder.springcloud.lab60.dto.UserCreateDTO"</span>,<span class="hljs-string">"rpcExt"</span>:<span class="hljs-string">""</span>,<span class="hljs-string">"enabled"</span>:<span class="hljs-keyword">true</span>}
</code></pre>
<p>② 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/metadata">http://127.0.0.1:9095/#/system/metadata</a> 地址，进入「系统管理 -&gt; 元数据」菜单，可以看到上述注册的元数据。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/56.png" alt="系统管理 -&gt; 元数据"></p>
<p>③ 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/plug/divide">http://127.0.0.1:9095/#/plug/divide</a> 地址，进入「插件列表 -&gt; Divide」菜单，看到<strong>选择器</strong>和<strong>规则</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/57.png" alt="插件列表 -&gt; springcloud"></p>
<p>点击<strong>选择器</strong> <code>/sc-user-service-api</code> 的「编辑」按钮，查看该选择器的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/58.png" alt="插件列表 -&gt; springcloud -&gt; 选择器"></p>
<p>点击<strong>规则</strong> <code>/sc-user-service-api/user/get</code> 的「编辑」按钮，查看该规则的具体信息。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/59.png" alt="插件列表 -&gt; Divide -&gt; 规则"></p>
<p>④ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/sc-user-service-api/user/get?id=1">http://127.0.0.1:9195/sc-user-service-api/user/get?id=1</a> 地址，转发到 <code>GET /user/get</code> 接口上。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/60.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>GET</code>。</li>
<li>请求参数，直接带在 URL 后面。</li>
</ul>
<p>⑤ 使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/sb-demo-api/user/create">http://127.0.0.1:9195/sb-demo-api/user/create</a> 地址，转发到 <code>POST /user/create</code> 接口上。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/61.png" alt="Postman 模拟"></p>
<ul>
<li>使用 Request <strong>Method</strong> 为 <code>POST</code>。</li>
<li>请求内容类型为 <code>application/json</code>。</li>
<li>因为 <code>POST /user/create</code> 使用 JSON 接参，所以直接在 Request <strong>Body</strong> 输入 JSON 数据格式。</li>
</ul>
<p>至此，我们已经完成了 Soul 网关接入 Spring Cloud 应用，并进行相应的而测试。</p>
<blockquote>
<p>友情提示：实际上，我们<strong>也</strong>可以参考<a href="https://dromara.org/zh-cn/docs/soul/plugin-springcloud.html">《Soul 文档 —— springcloud 插件》</a>，<strong>手动</strong>在 Soul Admin 控制台配置 API 接口方法的<strong>元数据</strong>，以及进行 springcloud 插件的<strong>选择器</strong>和<strong>规则</strong>的设置，实现 Soul Bootstrap 服务网关转发请求到 Spring Cloud 应用，<strong>无需</strong>在 Spring Cloud 应用中引入 <code>soul-client-springcloud</code> 依赖。</p>
<p>也就是说，引入 <code>soul-client-springcloud</code> 依赖的目的，是为了实现<strong>自动化</strong>，毕竟<strong>手工</strong>配置比较麻烦，并且容易出错。</p>
</blockquote>
<h1>6. rateLimiter 插件</h1>
<p>本小节，我们参考<a href="https://dromara.org/zh-cn/docs/soul/plugin-rateLimiter.html">《Soul 文档 —— rateLimiter 插件》</a>文章，使用 <strong>rateLimiter</strong> 插件，实现 Soul 网关的<strong>限流</strong>功能。该插件是基于令牌桶算法 + Redis 存储计数，实现<strong>分布式</strong>限流。整体设计如下图：</p>
<p><img src="http://static.iocoder.cn/645aa07113894d72b58ee85c8c4e5155.jpg" alt="原理"></p>
<p>下面，我们在<a href="#">「3. 接入 Dubbo 应用」</a>小节的基础上，对 <code>user-api/user/get</code> 实现<strong>限流</strong>的功能。</p>
<h2>6.1 安装 Redis</h2>
<p>相信大家都会，艿艿就不瞎哔哔了。嘿嘿~</p>
<h2>6.2 设置 rateLimiter 插件</h2>
<p>先需要设置 <a href="https://dromara.org/zh-cn/docs/soul/plugin-rateLimiter.html">rateLimiter 插件</a> 的 Redis 配置，目前支持单机、哨兵、集群模式。</p>
<p>① 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/plugin">http://127.0.0.1:9095/#/system/plugin</a> 地址，进入「系统管理 -&gt; 插件管理」菜单，可以看到 rateLimiter 插件。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/70.png" alt="系统管理 -&gt; 插件管理"></p>
<p>② 点击 rateLimiter 插件的「编辑」按钮，设置 Redis 的配置，并设置该插件为<strong>开启</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/71.png" alt="系统管理 -&gt; 插件管理 -&gt; 编辑"></p>
<blockquote>
<p>友情提示：Redis 的地址，记得要填写正确哈~</p>
</blockquote>
<p>③ 因为 Soul Bootstrap 和 Soul Admin 暂时不支持插件修改的<strong>自动加载</strong>，所以我们此时需要<strong>手动重启</strong>下。</p>
<h2>6.3 设置 rateLimiter 限流规则</h2>
<p>① 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/plug/rate_limiter">http://127.0.0.1:9095/#/plug/rate_limiter</a> 地址，进入「插件列表 -&gt; rate_limiter」菜单，进行限流规则的配置。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/72.png" alt="插件列表 -&gt; rate_limiter"></p>
<p>② 点击「添加选择器」按钮，添加一个<strong>选择器</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/73.png" alt="插件列表 -&gt; rate_limiter -&gt; 添加选择器"></p>
<p>③ 点击「添加规则」按钮，给该选择器添加一个<strong>规则</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/74.png" alt="插件列表 -&gt; rate_limiter -&gt; 添加规则"></p>
<ul>
<li>对请求地址 <code>/user-api/user/get</code> 进行限流，对应 UserService 的 <code>#getUser(Integer id)</code> 方法。</li>
<li><strong>速率</strong>：是你允许用户每秒执行多少请求，而丢弃任何请求。这是令牌桶的填充速率。</li>
<li><strong>容量</strong>：是允许用户在一秒钟内执行的最大请求数。这是令牌桶可以保存的令牌数。</li>
</ul>
<blockquote>
<p>友情提示：可能胖友对 Soul 定义的<strong>选择器</strong>与<strong>规则</strong>的概念有点不了解，可以看看<a href="https://dromara.org/zh-cn/docs/soul/selector.html">《Soul 文档 —— 选择器规则详解》</a>文章。</p>
</blockquote>
<h2>6.4 简单测试</h2>
<p>执行 UserServiceApplication 启动 Dubbo 服务。</p>
<p><strong>快速</strong>且<strong>多次</strong>使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/user-api/user/get">http://127.0.0.1:9195/user-api/user/get</a> 地址，调用 <code>UserServiceImpl#getUser(Integer id)</code> 方法，最终被<strong>限流</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/75.png" alt="Postman 模拟"></p>
<h1>7. hystrix 插件</h1>
<p>本小节，我们参考<a href="https://dromara.org/zh-cn/docs/soul/plugin-hystrix">《Soul 文档 —— hystrix 插件》</a>文章，使用 <strong>hystrix</strong> 插件，使用 <a href="http://www.iocoder.cn/categories/Hystrix/?self">Hystrix</a> 框架，实现 Soul 网关的<strong>熔断器</strong>功能。</p>
<blockquote>
<p>友情提示：对 Hystrix 不了解的胖友，可以后续阅读<a href="http://www.iocoder.cn/Spring-Boot/Hystrix/?self">《芋道 Spring Boot 服务容错 Hystrix 入门》</a>文章进行学习。</p>
</blockquote>
<p>下面，我们在<a href="#">「3. 接入 Dubbo 应用」</a>小节的基础上，对 <code>user-api/user/get</code> 实现<strong>熔断器</strong>的功能。</p>
<h2>7.1 设置 hystrix 插件</h2>
<p>需要设置 <a href="https://dromara.org/zh-cn/docs/soul/plugin-hystrix.html">hystrix 插件</a> 为<strong>开启</strong>。</p>
<p>使用浏览器，访问 <a href="http://127.0.0.1:9095/#/system/plugin">http://127.0.0.1:9095/#/system/plugin</a> 地址，进入「系统管理 -&gt; 插件管理」菜单，可以看到 hystrix 插件。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/80.png" alt="系统管理 -&gt; 插件管理"></p>
<p>默认情况下，hystrix 插件已经是<strong>开启</strong>状态，所以无需开启。</p>
<h2>7.2 设置 rateLimiter 限流规则</h2>
<p>① 使用浏览器，访问 <a href="http://127.0.0.1:9095/#/plug/hystrix">http://127.0.0.1:9095/#/plug/hystrix</a> 地址，进入「插件列表 -&gt; hystrix」菜单，进行熔断器规则的配置。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/81.png" alt="插件列表 -&gt; hystrix"></p>
<p>② 点击「添加选择器」按钮，添加一个<strong>选择器</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/82.png" alt="插件列表 -&gt; hystrix -&gt; 添加选择器"></p>
<p>③ 点击「添加规则」按钮，给该选择器添加一个<strong>规则</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/83.png" alt="插件列表 -&gt; hystrix -&gt; 添加规则"></p>
<ul>
<li>对请求地址 <code>/user-api/user/get</code> 进行熔断保护，对应 UserService 的 <code>#getUser(Integer id)</code> 方法。</li>
</ul>
<blockquote>
<p>友情提示：可能胖友对 Soul 定义的<strong>选择器</strong>与<strong>规则</strong>的概念有点不了解，可以看看<a href="https://dromara.org/zh-cn/docs/soul/selector.html">《Soul 文档 —— 选择器规则详解》</a>文章。</p>
</blockquote>
<h2>7.3 简单测试</h2>
<p><strong>不要</strong>执行 UserServiceApplication 启动 Dubbo 服务，模拟其<strong>故障</strong>。</p>
<p><strong>快速</strong>且<strong>多次</strong>使用 Postman 模拟请求 <a href="http://127.0.0.1:9195/user-api/user/get">http://127.0.0.1:9195/user-api/user/get</a> 地址，调用 <code>UserServiceImpl#getUser(Integer id)</code> 方法，最终被<strong>熔断</strong>。如下图所示：</p>
<p><img src="http://www.iocoder.cn/images/Soul/84.png" alt="Postman 模拟"></p>
<p>此时，我们在 Soul Bootstrap 网关的日志可以看到，Hystrix 熔断器已经打开。日志内容如下：</p>
<pre><code class="language-Java"><span class="hljs-number">2020</span>-<span class="hljs-number">05</span>-<span class="hljs-number">23</span> <span class="hljs-number">20</span>:<span class="hljs-number">52</span>:<span class="hljs-number">28.786</span> ERROR <span class="hljs-number">69264</span> --- [work-threads-<span class="hljs-number">20</span>] o.d.s.web.plugin.hystrix.HystrixPlugin   : hystrix execute have circuitBreaker is Open! groupKey:user-service,commandKey:cn.iocoder.springboot.lab60.userservice.api.UserService
</code></pre>
<h1>666. 彩蛋</h1>
<p>至此，我们已经完成了 Soul 网关的学习，后续胖友可以阅读<a href="https://dromara.org/zh-cn/docs/soul/soul.html">《Soul 文档》</a>，了解本文暂时并未写到的内容。</p>
<p>例如<strong>插件</strong>相关：</p>
<ul>
<li><a href="https://dromara.org/zh-cn/docs/soul/plugin-monitor.html">monitor 插件</a>：实现监控数据的收集，后续可以使用 <a href="http://www.iocoder.cn/Prometheus/install/?self">Grafana</a> 实现监控仪表盘。</li>
<li><a href="https://dromara.org/zh-cn/docs/soul/plugin-waf.html">waf 插件</a>：实现黑名单功能，禁止恶意 IP 的访问。</li>
<li><a href="https://dromara.org/zh-cn/docs/soul/plugin-sign.html">sign 插件</a>：实现请求签名功能，保证接口的安全性。</li>
<li><a href="https://dromara.org/zh-cn/docs/soul/plugin-rewrite.html">rewrite 插件</a>：对请求 URI 进行重写。</li>
<li><a href="https://dromara.org/zh-cn/docs/soul/plugin-websocket.html">websocket 插件</a>：实现对 Websocket 进行代理转发。</li>
<li><a href="https://dromara.org/zh-cn/docs/soul/dev-plugin.html">自定义插件</a>：自己实现插件，进一步拓展自己的插件。</li>
</ul>
<p>例如<strong>功能</strong>相关：</p>
<ul>
<li>
<p><a href="https://dromara.org/zh-cn/docs/soul/dev-filter.html">自定义 filter</a>：自定义 Filter，可以拓展安全认证等等功能。</p>
</li>
<li>
<p><a href="https://dromara.org/zh-cn/docs/soul/dev-file.html">文件上传下载</a>：提供的文件上传和下载功能。</p>
<blockquote>
<p>友情提示：建议文件上传不要经过 API 网关，而是先上传到文件服务器，然后提交 URL 到 API 网关。</p>
</blockquote>
</li>
<li>
<p><a href="https://dromara.org/zh-cn/docs/soul/dev-iphost.html">自定义 host 与 ip</a>：考虑到 API 网关的前面都有 Nginx，所以需要拓展保证解析到正确的用户 IP。</p>
</li>
<li>
<p><a href="https://dromara.org/zh-cn/docs/soul/dev-result.html">自定义返回结果</a>：每个公司的统一返回格式可能有差异，最好自己拓展下。</p>
</li>
</ul>
</div></section><footer class="footer-container"><div class="footer-body"><img src="/website/img/dromara.png"/><div class="cols-container"><div class="col col-12"><h3>免责声明</h3><p>任何单位或个人转载本网站的所有相关信息，请注明来源。</p></div><div class="col col-6"><dl><dt>文档</dt><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">概览</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">快速开始</a></dd><dd><a href="/website/zh-cn/docs/soul/soul.html" target="_self">开发者指南</a></dd></dl></div><div class="col col-6"><dl><dt>资源</dt><dd><a href="/website/zh-cn/blog/index.html" target="_self">博客</a></dd><dd><a href="/website/zh-cn/community/index.html" target="_self">社区</a></dd></dl></div></div><div class="copyright"><span>Copyright ©2020 xiaoyu@apache.org by xiaoyu</span></div></div></footer></div></div>
	<script src="https://f.alicdn.com/react/15.4.1/react-with-addons.min.js"></script>
	<script src="https://f.alicdn.com/react/15.4.1/react-dom.min.js"></script>
	<script>
		window.rootPath = '/website';
  </script>
	<script src="/website/build/documentation.js"></script>
</body>
</html>